<?php

namespace App\Http\Controllers\Auth;

use App\Http\Common\Globals;
use App\Http\Common\MyUtils;
use App\Http\Controllers\BaseController;
use App\Models\Group;
use App\Models\UserGroup;
use App\Models\UserRole;
use App\Models\WyOperaors;
use App\User;
use Exception;
use Illuminate\Contracts\View\Factory;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class RegisterController extends BaseController
{
    use RegistersUsers;

    /**
     * 注册账号 保存传递的数据
     * @param $request
     * @return User|bool
     */
    public function postRegister($request)
    {
        if (!isset($request['avatar']))$request['avatar'] = MyUtils::getSessionConfig('AVATAR');
        $res = $this->validatorRegister($request);
        $res_ = $res->messages()->getMessages();
        if (count($res_)==0){//验证请求的数据
            $key = $this->create($request);
            if ($key) {
                return $key;// 保存成功拿到id
            }
            else {
                Globals::$error = $res_;// 保存错误
                return false;
            }
        }else{
            Globals::$error = $res_;// 保存错误
            return false;
        }
    }

    /**
     * 自动分配角色
     * @param $request
     * @param $user_id
     * @return bool
     */
    public function assignRole($request,$user_id){
        $groupId = MyUtils::sg($request,"group_id");
        $roleId = 0;
        $group = Group::find($groupId);
        if ($group){
            switch ($group->group_table_name){
                case "wy_operator":
                    $roleId = 2;
                    break;
                case "wy_property":
                    $roleId = 3;
                    break;
                case "wy_area":
                    $roleId = 4;
                    break;
                case "csyys_business":
                    $roleId = 5;
                    break;
                case "developer":
                    $roleId = 6;
                    break;
                case "wy_operator_no_tc":
                    $roleId = 7;
                    break;
                default:
                    $roleId = 0;
            }
        }
        if ($roleId==0){
            Globals::$error = "该角色不存在，请确定组是否正确";
            return false;
        }
        $params = ["role_id"=>$roleId,"user_id"=>$user_id];
        $roleCount = UserRole::where(["user_id"=>$user_id])->count();
        if ($roleCount==0){// 表示用户没有该角色
            UserRole::insertGetId($params);
        }else{
            Globals::$error = "该用户已经被分配其他角色，不能再次分配角色";
            $thisRoleCount = UserRole::where($params)->count();// 当前角色数量
            if ($thisRoleCount){
                return true;
            }else{
                return false;
            }
        }
        return true;
    }

    public function getLevel($request,$level=0){
        $group = Group::where("id",$request['group_id'])->first();
        $parent_id = MyUtils::sg($group,"parent_id");
        if ($parent_id){
            $group = Group::where("id",$parent_id)->first();
            $request['group_id'] = MyUtils::sg($group,"id");
            $level = $this->getLevel($request,++$level);
        }
        return $level;
    }

    /**
     * 注册手机端账号 保存传递的数据
     * @param $request
     * @return User|bool
     */
    public function postPhoneRegister($request)
    {
        if (!isset($request['avatar']))$request['avatar'] = MyUtils::getSessionConfig('AVATAR');
        $res = $this->validatorPhoneRegister($request);
        $res_ = $res->messages()->getMessages();
        if (count($res_)==0){//验证请求的数据
            $key = $this->phoneCreate($request);
            if ($key) {
                return $key;// 保存成功拿到id
            }
            else {
                Globals::$error = $res_;// 保存错误
                return false;
            }
        }else{
            Globals::$error = $res_;// 保存错误
            return false;
        }
    }

    /**
     * 更新账号 保存传递的数据
     * @param $request
     * @return Factory|View
     */
    public function postUpdate($request)
    {
        if (!isset($request['avatar']))$request['avatar'] = MyUtils::getSessionConfig('AVATAR');
        $res = $this->validatorUpdate($request);
        $res_ = $res->messages()->getMessages();
        if (count($res_)==0){//验证请求的数据
            $key = $this->updateSelf($request);
            if ($key) {
                return $key;// 保存成功拿到id
            }
            else {
                Globals::$error = $res_;// 保存错误
                return false;
            }
        }else{
            Globals::$error = $res_;// 保存错误
            return false;
        }
    }
    /**
     * 更新电话的账号 保存传递的数据
     * @param $request
     * @return Factory|View
     */
    public function postPhoneUpdate($request)
    {
        if (!isset($request['avatar']))$request['avatar'] = MyUtils::getSessionConfig('AVATAR');
        $res = $this->validatorPhoneUpdate($request);
        $res_ = $res->messages()->getMessages();
        if (count($res_)==0){//验证请求的数据
            $key = $this->updatePhoneSelf($request);
            if ($key) {
                return $key;// 保存成功拿到id
            }
            else {
                Globals::$error = $res_;// 保存错误
                return false;
            }
        }else{
            Globals::$error = $res_;// 保存错误
            return false;
        }
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validatorRegister(array $data)
    {
        try{
            return Validator::make($data, [
                'username' => ['required', Rule::unique('users')->whereNull('deleted_at'), 'string', 'min:1', 'max:255'],
                'phone' => ['required', Rule::unique('users')->whereNull('deleted_at')->where(function ($query)use($data) {
                    $query->where('user_type', MyUtils::sg($data,'user_type',2));
                }),'string', 'max:255','mobile'],
                'email' => [Rule::unique('users')->whereNull('deleted_at'),'string', 'email', 'max:255'],
                'password' => ['required', 'min:6', 'max:16'],
                'avatar' => ['required', 'string']
            ]);
        }catch (Exception $e){
            Globals::$error .= json_encode($e);
            return false;
        }
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validatorPhoneRegister(array $data)
    {
        try{
            return Validator::make($data, [
                'username' => ['required', 'unique:users', 'string', 'min:1', 'max:255'],
                'phone' => [Rule::unique('users')->where(function ($query)use($data) {
                    return $query->where(['user_type'=>MyUtils::sg($data,'user_type',2)]);
                }),'string', 'max:255','mobile'],
                'password' => ['required', 'string', 'min:6', 'max:16'],
                'avatar' => ['required', 'string']
            ]);
        }catch (Exception $e){
            Globals::$error .= json_encode($e);
            return false;
        }
    }

    protected function validatorUpdate(array $data)
    {
        try{
            if (!MyUtils::sg($data,'password')){
                return Validator::make($data, [
                    'username' => ['required', Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at'), 'string', 'min:1', 'max:255'],
                    'phone' => ['required', Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at')->where(function ($query)use($data) {
                        return $query->where(['user_type'=>MyUtils::sg($data,'user_type',2)]);
                    }), 'string', 'min:1', 'max:255','mobile'],
                    'email' => ['string', 'email', 'max:255', Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at'),],
                    'avatar' => ['required', 'string']
                ]);
            }else{
                return Validator::make($data, [
                    'username' => ['required', Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at'), 'string', 'min:1', 'max:255'],
                    'phone' => ['required', Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at')->where(function ($query)use($data) {
                        return $query->where(['user_type'=>MyUtils::sg($data,'user_type',2)]);
                    }), 'string', 'min:1', 'max:255','mobile'],
                    'email' => ['string', 'email', 'max:255', Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at'),],
                    'password' => ['string', 'min:6', 'max:16'],
                    'avatar' => ['required', 'string']
                ]);
            }
        }catch (Exception $e){
            Globals::$error .= json_encode($e);
            return false;
        }
    }

    protected function validatorPhoneUpdate(array $data)
    {
        try{
            if (!MyUtils::sg($data,'password')){
                return Validator::make($data, [
                    'username' => ['required', Rule::unique('users')->ignore($data['id']), 'string', 'min:1', 'max:255'],
                    'phone' => [Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at')->where(function ($query)use($data) {
                        return $query->where(['user_type'=>MyUtils::sg($data,'user_type',2)]);
                    }), 'string', 'min:1', 'max:255','mobile'],
                    'avatar' => ['required', 'string']
                ]);
            }else{
                return Validator::make($data, [
                    'username' => ['required', Rule::unique('users')->ignore($data['id']), 'string', 'min:1','max:255'],
                    'phone' => [Rule::unique('users')->ignore($data['id'])->whereNull('deleted_at')->where(function ($query)use($data) {
                        return $query->where(['user_type'=>MyUtils::sg($data,'user_type',2)]);
                    }), 'string', 'min:1', 'max:255','mobile'],
                    'password' => ['string', 'min:6', 'max:16'],
                    'avatar' => ['required', 'string']
                ]);
            }

        }catch (Exception $e){
            Globals::$error .= json_encode($e);
            return false;
        }
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    protected function create(array $data)
    {
        $openid = $this->getUniqueOpenid($data);
        $pass = Hash::make($data['password']);
        Redis::set("user_openids:".$openid,md5($openid.$pass));// redis里面设置每个用户的唯一码（密码修改了就不一样了）
        $res = User::create([
            'username' => $data['username'],
            'email' => MyUtils::sg($data,'email'),
            'password' => $pass,
            'openid' => $openid,
            'phone' => $data['phone'],
            'project_id' => $data['project_id'],
            'user_type' => MyUtils::sg($data,'user_type',2),
            'avatar' => $data['avatar'],
            'nickname' => $data['nickname'],
        ]);
        $user = User::where('openid',$openid)->get('id')->first();
        $groupCount = UserGroup::where(["user_id"=>$user->id])->count();
        if ($groupCount==0){// 表示用户没有该角色
            UserGroup::insert(['user_id'=>MyUtils::sg($user,'id'),'group_id'=>MyUtils::sg($data,"group_id")]);
        }else{
            Globals::$error = "该用户已经被分配其他组，不能再次分配组";
            return false;
        }
        $assign = $this->assignRole($data,MyUtils::sg($user,'id'));// 分配 用户角色
        if (!$assign){
            return false;
        }
        if ($res) {
            return $res->id;
        }
        return $res;
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    protected function phoneCreate(array $data)
    {
        $openid = $this->getUniqueOpenid($data);
        $pass = Hash::make($data['password']);
        Redis::set("user_openids:".$openid,md5($openid.$pass));// redis里面设置每个用户的唯一码（密码修改了就不一样了）
        $res = User::create([
            'username' => MyUtils::sg($data,'username'),
            'email' => MyUtils::sg($data,'email'),
            'password' => $pass,
            'openid' => $openid,
            'phone' => MyUtils::sg($data,'phone'),
            'user_type' => MyUtils::sg($data,'user_type',2),
            'project_id' => MyUtils::sg($data,'project_id'),
            'avatar' => MyUtils::sg($data,'avatar'),
            'nickname' => MyUtils::sg($data,'nickname'),
        ]);
        $user = User::where('openid',$openid)->get('id')->first();
        $groupCount = UserGroup::where(["user_id"=>$user->id])->count();
        if ($groupCount==0){// 表示用户没有该角色
            UserGroup::insert(['user_id'=>MyUtils::sg($user,'id'),'group_id'=>MyUtils::sg($data,"group_id")]);
        }else{
            Globals::$error = "该用户已经被分配其他组，不能再次分配组";
            return false;
        }
        $assign = $this->assignRole($data,MyUtils::sg($user,'id'));// 分配 用户角色
        if (!$assign){
            return false;
        }
        if ($res){
            return $res->id;
        }
        return $res;
    }

    /**
     * 更新
     * @param array $data
     * @return mixed
     */
    public function updateSelf(array $data)
    {
        $user = User::where("id",$data['id'])->first();
        if (isset($data['password']) == "" || $data['password'] == null){//为空默认不修改
            $temp= [
                'username' => $data['username'],
                'email' => MyUtils::sg($data,'email'),
                'phone' => $data['phone'],
                'avatar' => $data['avatar'],
                'nickname' => $data['nickname'],
            ];
        }else{
            $pass = Hash::make($data['password']);
            $openid = MyUtils::sg($user,'openid');
            Redis::set("user_openids:".$openid,md5($openid.$pass));// redis里面设置每个用户的唯一码（密码修改了就不一样了），
            $temp = [
                'username' => $data['username'],
                'email' => MyUtils::sg($data,'email'),
                'password' => $pass,
                'phone' => $data['phone'],
                'avatar' => $data['avatar'],
                'nickname' => $data['nickname'],
            ];
        }
        $res = DB::transaction(function () use($data,$user,$temp){
            $groupId = MyUtils::sg($data,"group_id");
            $userId = MyUtils::sg($user,'id');
            $res1 = true;
            if ($groupId){
                $params = ['user_id'=>$userId,'group_id'=>$groupId];
                $res = UserGroup::where(['user_id'=>$userId])->delete();
                if ($res===false){
                    DB::rollBack();
                    return false;
                }
                $count = UserGroup::where($params)->count();
                if (!$count){// 用户组的数据 如果存在，就不再新增，没有就新增
                    Globals::$success = "修改成功！";
                    $res1 = UserGroup::insert($params);
                }
            }
            $res = $user->update($temp);
            if ($res && $res1) {
                Globals::$success = "修改成功！";
                DB::commit();
                return $res;
            }else{
                Globals::$error = "修改失败！";
                DB::rollBack();
                return false;
            }
        });
        return $res;
    }

    /**
     * 更新
     * @param array $data
     * @return mixed
     */
    public function updatePhoneSelf(array $data)
    {
        $user = User::where("id",$data['id'])->first();
        if (isset($data['password']) == "" || $data['password'] == null){//为空默认不修改
            $temp= [
                'username' => MyUtils::sg($data,'username'),
                'email' => MyUtils::sg($data,'email'),
                'phone' => MyUtils::sg($data,'phone'),
                'avatar' => MyUtils::sg($data,'avatar'),
                'nickname' => MyUtils::sg($data,'nickname'),
            ];
            $temp = array_filter($temp);
        }else{
            $pass = Hash::make($data['password']);
            $openid = MyUtils::sg($user,'openid');
            Redis::set("user_openids:".$openid,md5($openid.$pass));// redis里面设置每个用户的唯一码（密码修改了就不一样了），
            $temp= [
                'username' => MyUtils::sg($data,'username'),
                'email' => MyUtils::sg($data,'email'),
                'phone' => MyUtils::sg($data,'phone'),
                'avatar' => MyUtils::sg($data,'avatar'),
                'nickname' => MyUtils::sg($data,'nickname'),
                'password' => $pass,
            ];
            $temp = array_filter($temp);
        }
        $res = DB::transaction(function () use($data,$user,$temp){
            $groupId = MyUtils::sg($data,"group_id");
            $userId = MyUtils::sg($user,'id');
            $res1 = true;
            if ($groupId){
                $params = ['user_id'=>$userId,'group_id'=>$groupId];
                $res = UserGroup::where(['user_id'=>$userId])->delete();
                if ($res===false){
                    DB::rollBack();
                    return false;
                }
                $count = UserGroup::where($params)->count();
                if (!$count){// 用户组的数据 如果存在，就不再新增，没有就新增
                    Globals::$success = "修改成功！";
                    $res1 = UserGroup::insert($params);
                }
            }
            $res = $user->update($temp);
            if ($res && $res1) {
                Globals::$success = "修改成功！";
                return $res;
            }else{
                Globals::$error = "修改失败！";
                DB::rollBack();
                return false;
            }
        });
        return $res;
    }

    /**
     * 得到唯一的openoid
     */
    public function getUniqueOpenid($data){
        // 得到唯一的openId
        $openId = Hash::make($data['username'].$data['password'].MyUtils::randName());
        $user = User::where('openid',$openId)->get()->count();
        // 不为空 再生成一遍
        if ($user) $openId = $this->getUniqueOpenid($data);
        return $openId;
    }

}
